package coupon

import (
	sqlc "bp/db/sqlc"
	sharedConv "bp/internal/rpcserver/shared/conv"
	"bp/internal/service/param"
	couponGrpc "bp/rpc/gen/webapi/coupon"
)

type CouponPtrEntityToPbFunc func(*sqlc.Coupon) *couponGrpc.CouponEntity
type CouponPtrArrayEntityToPbFunc func([]*sqlc.Coupon) []*couponGrpc.CouponEntity

// ConvCouponPtrEntityToPb get func of *sqlc.Coupon => *couponGrpc.CouponEntity
func (s *CouponWebApiImp) ConvCouponPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) CouponPtrEntityToPbFunc {
	return func(ptr *sqlc.Coupon) *couponGrpc.CouponEntity {
		if ptr == nil {
			return nil
		}
		return &couponGrpc.CouponEntity{
			Id:                      ptr.ID,
			OwnerType:               ptr.OwnerType,
			OwnerId:                 ptr.OwnerID,
			Name:                    ptr.Name,
			Desc:                    ptr.Desc.String,
			Tags:                    ptr.Tags,
			Nature:                  ptr.Nature,
			OfferCategory:           ptr.OfferCategory,
			OfferType:               ptr.OfferType,
			CouponStatus:            ptr.CouponStatus,
			Published:               sqlc.GoNTimeToPBTimestamp(ptr.Published),
			Paused:                  sqlc.GoNTimeToPBTimestamp(ptr.Paused),
			Resumed:                 sqlc.GoNTimeToPBTimestamp(ptr.Resumed),
			Closed:                  sqlc.GoNTimeToPBTimestamp(ptr.Closed),
			Bg:                      ptr.Bg.String,
			NeedVerifyQualification: ptr.NeedVerifyQualification,
			QualifyTypes:            ptr.QualifyTypes,
			Price:                   ptr.Price,
			Quota:                   ptr.Quota,
			OffMaximum:              ptr.OffMaximum,
			UsePeriodType:           ptr.UsePeriodType,
			Days:                    ptr.Days.Int32,
			AvailableAfterGotDays:   ptr.AvailableAfterGotDays.Int32,
			UseBegined:              sqlc.GoNTimeToPBTimestamp(ptr.UseBegined),
			UseEnded:                sqlc.GoNTimeToPBTimestamp(ptr.UseEnded),
			UseTimeRanges:           sharedConv.ConvTimeRangeArrayEntityToPb(ptr.UseTimeRanges),
			DateChooseType:          ptr.DateChooseType.String,
			Weekdays:                ptr.Weekdays,
			Monthdays:               ptr.Monthdays,
			UseScenes:               ptr.UseScenes,
			Scope:                   ptr.Scope,
			ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
			ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
			Maximum:                 ptr.Maximum,
			MaxiumGotFrequency:      ptr.MaxiumGotFrequency,
		}
	}
}

// ConvCouponPtrArrayEntityToPb get func of []*sqlc.Coupon => []*couponGrpc.CouponEntity
func (s *CouponWebApiImp) ConvCouponPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
) CouponPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.Coupon) (vPtrs []*couponGrpc.CouponEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		for _, ptr := range ptrs {
			if itemCategoryMap != nil {
				itemCategoryPtrs = itemCategoryMap[ptr.ID]
			}
			if itemMap != nil {
				itemPtrs = itemMap[ptr.ID]
			}
			vPtrs = append(vPtrs, s.ConvCouponPtrEntityToPb(itemCategoryPtrs, itemPtrs)(ptr))
		}
		return
	}
}

type CouponWithStatPtrEntityToPbFunc func(*sqlc.ListCouponWithStatsRow) *couponGrpc.CouponWithStatEntity
type CouponWithStatPtrArrayEntityToPbFunc func([]*sqlc.ListCouponWithStatsRow) []*couponGrpc.CouponWithStatEntity

// ConvCouponPtrEntityToPb get func of *sqlc.ListCouponWithStatsRow => *couponGrpc.CouponWithStatEntity
func (s *CouponWebApiImp) ConvCouponWithStatPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) CouponWithStatPtrEntityToPbFunc {
	return func(ptr *sqlc.ListCouponWithStatsRow) *couponGrpc.CouponWithStatEntity {
		if ptr == nil {
			return nil
		}
		return &couponGrpc.CouponWithStatEntity{
			Self: &couponGrpc.CouponEntity{
				Id:                      ptr.ID,
				OwnerType:               ptr.OwnerType,
				OwnerId:                 ptr.OwnerID,
				Name:                    ptr.Name,
				Desc:                    ptr.Desc.String,
				Tags:                    ptr.Tags,
				Nature:                  ptr.Nature,
				OfferCategory:           ptr.OfferCategory,
				OfferType:               ptr.OfferType,
				CouponStatus:            ptr.CouponStatus,
				Published:               sqlc.GoNTimeToPBTimestamp(ptr.Published),
				Paused:                  sqlc.GoNTimeToPBTimestamp(ptr.Paused),
				Resumed:                 sqlc.GoNTimeToPBTimestamp(ptr.Resumed),
				Closed:                  sqlc.GoNTimeToPBTimestamp(ptr.Closed),
				Bg:                      ptr.Bg.String,
				NeedVerifyQualification: ptr.NeedVerifyQualification,
				QualifyTypes:            ptr.QualifyTypes,
				Price:                   ptr.Price,
				Quota:                   ptr.Quota,
				OffMaximum:              ptr.OffMaximum,
				UsePeriodType:           ptr.UsePeriodType,
				Days:                    ptr.Days.Int32,
				AvailableAfterGotDays:   ptr.AvailableAfterGotDays.Int32,
				UseBegined:              sqlc.GoNTimeToPBTimestamp(ptr.UseBegined),
				UseEnded:                sqlc.GoNTimeToPBTimestamp(ptr.UseEnded),
				UseTimeRanges:           sharedConv.ConvTimeRangeArrayEntityToPb(ptr.UseTimeRanges),
				DateChooseType:          ptr.DateChooseType.String,
				Weekdays:                ptr.Weekdays,
				Monthdays:               ptr.Monthdays,
				UseScenes:               ptr.UseScenes,
				Scope:                   ptr.Scope,
				ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
				ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
				Maximum:                 ptr.Maximum,
				MaxiumGotFrequency:      ptr.MaxiumGotFrequency,
			},
			Stat: &couponGrpc.CouponStatEntity{
				DistributedCnt:    ptr.DistributedCnt,
				GotCnt:            ptr.GotCnt,
				UseCnt:            ptr.UseCnt,
				UseAmount:         ptr.UseAmount,
				OffTransCnt:       ptr.OffTransCnt,
				OffAmount:         ptr.OffAmount,
				OffRefundTransCnt: ptr.OffRefundTransCnt,
				OffRefundAmount:   ptr.OffRefundAmount,
			},
		}
	}
}

// ConvCouponWithStatPtrArrayEntityToPb get func of []*sqlc.ListCouponWithStatsRow => []*couponGrpc.CouponWithStatEntity
func (s *CouponWebApiImp) ConvCouponWithStatPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
) CouponWithStatPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.ListCouponWithStatsRow) (vPtrs []*couponGrpc.CouponWithStatEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		for _, ptr := range ptrs {
			if itemCategoryMap != nil {
				itemCategoryPtrs = itemCategoryMap[ptr.ID]
			}
			if itemMap != nil {
				itemPtrs = itemMap[ptr.ID]
			}
			vPtrs = append(vPtrs, s.ConvCouponWithStatPtrEntityToPb(itemCategoryPtrs, itemPtrs)(ptr))
		}
		return
	}
}
